/*
 * Copyright 2010 Christoph Widulle (christoph.widulle@googlemail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */


package com.android1.amarena2d.actions.base;

import com.android1.amarena2d.nodes.behavior.ActionTarget;

public class Repeat extends IntervalAction {

    private int times;
    private int count;
    private FiniteTimeAction other;

    public static Repeat $(int times, FiniteTimeAction action) {
        return new Repeat(times, action);
    }

    public Repeat(int times, FiniteTimeAction action) {
        super(action.getDuration() * times);
        this.times = times;
        other = action;
    }

    public Repeat reset(int times, FiniteTimeAction action) {
        duration = action.getDuration() * times;
        this.times = times;
        this.other = action;
        return this;
    }

    @Override
    public void start(ActionTarget target) {
        count = 0;
        super.start(target);
        other.start(target);
    }

    @Override
    public void stop() {
        other.stop();
        super.stop();
    }
//
//    @Override
//    public void finished(ActionTarget actionTarget) {
//        other.finished(actionTarget);
//        super.finished(actionTarget);
//    }

    //todo test this
    @Override
    public void update(float time) {
        float t = time * times;
        if (t > count + 1) {
            other.update(1.0f);
            count++;
            other.stop();
            other.complete(target);
            other.start(target);
            // repeat is over ?
            if (count == times)
                // so, set it in the original position
                other.update(0);
            else {
                // no ? start next repeat with the right update
                // to prevent jerk (issue #390)
                other.update(t - count);
            }

        } else {
            float r = t % 1.0f;
            // fix last repeat position
            // else it could be 0.
            if (time == 1.0f) {
                r = 1.0f;
                count++;
                other.stop();
                other.complete(target);
                other.start(target);
            }
            other.update(Math.min(r, 1));
        }
    }

    @Override
    public boolean isDone() {
        return (count >= times);
    }

    @Override
    public Repeat copy() {
        return Repeat.$(times, other.copy());
    }

    @Override
    public Repeat reverse() {
        return Repeat.$(times, other.reverse());
    }
}
